// // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// //
// // Licensed under the Apache License, Version 2.0 (the "License");
// // you may not use this file except in compliance with the License.
// // You may obtain a copy of the License at

// //     http://www.apache.org/licenses/LICENSE-2.0
// //
// // Unless required by applicable law or agreed to in writing, software
// // distributed under the License is distributed on an "AS IS" BASIS,
// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// // See the License for the specific language governing permissions and
// // limitations under the License.

// #include <stdint.h>
// #include <string.h>
// #include <stdbool.h>
// #include "spp_task.h"
// #include "spp_command_process.h"
// #include "esp_log.h"
// #include "esp_system.h"
// #include "esp_camera.h"
// #include "soc/uart_struct.h"
// #include "driver/uart.h"
// #include "esp_bt_device.h"

// #define UART_USED UART_NUM_2
// #define uart_sendssidpwd(n) uart_sendstring(n)
// #define uart_send(data, len) uart_write_bytes(UART_USED, (const char* )data, len)


// char * TAG = "SPP_CMD";

// uint8_t send_port_flag = BT_PORT_SEND;
// uint8_t send_buff[1034];
// SendPackStruct_S pack_head_s;
// update_info_s update_info;
// #define MAX_BT_NAME_SIZE 32
// uint8_t bt_name[MAX_BT_NAME_SIZE] = {0};
// void set_send_port(uint8_t port) {
//     send_port_flag = port;
// }

// /**
//  *设置应答
//  *para opcode:应答控制字
//  *     result:处理结果
//  *     pdata:数据区，如果为NULL，表示没数据
//  *     len:数据长度
//  */
// void bt_sendprotocoldata(uint8_t opcode, uint8_t result, uint8_t *pdata, uint16_t len)
// {
// 	uint16_t data_len = 0;
// 	uint32_t checksum = 0;
//     uint8_t retry;
// 	//包添加数据
// 	data_len = len + 2;//算上pack_opcode 和 pack_result 的长度
// 	//包头
// 	pack_head_s.head.pack_head1 = 0xAA;
// 	pack_head_s.head.pack_head2 = 0x55;
// 	//包长
// 	pack_head_s.head.pack_len_h = (uint8_t)(data_len >> 8);
// 	pack_head_s.head.pack_len_l = (uint8_t)data_len;
// 	//协议版本号
// 	pack_head_s.head.pack_version = 0x00;
// 	//包长校验
// 	pack_head_s.head.pack_len_check = pack_head_s.head.pack_len_h ^ pack_head_s.head.pack_len_l;
// 	//EventID
// 	pack_head_s.pack_opcode = opcode;
// 	pack_head_s.pack_result = result;

// 	//校验
// 	checksum = data_check(opcode, result, pdata, len);
// 	pack_head_s.head.pack_data_check_h = checksum >> 8;
// 	pack_head_s.head.pack_data_check_l = checksum;
//     if (send_port_flag == BT_PORT_SEND) {
//         retry = 3;
//         while(retry--) {
//             if(ssp_write_data((uint8_t*)&pack_head_s, sizeof(SendPackStruct_S)) == true)
//                 break;
//         }
//         if (retry == 0) {
//             ESP_LOGE(TAG, "bt send fail");
//         }
//     } else {
//         uart_send((uint8_t*)&pack_head_s,  sizeof(SendPackStruct_S));
//     }
//     if (pdata != NULL) {
//         if (send_port_flag == BT_PORT_SEND) {
//             retry = 3;
//             while(retry--) {
//                 if(ssp_write_data(pdata, len) == true)
//                     break;
//             }
//             if (retry == 0) {
//                 ESP_LOGE(TAG, "bt send fail");
//             }
//         }else {
//             uart_send(pdata, len);
//         }
//     }
// }

// void send_err_code(uint8_t opcode, uint8_t result, uint16_t err) {
//     send_buff[0] = err >> 8;
//     send_buff[1] = err;
//     ESP_LOGE(TAG, "send err opcode:0x%x, result:0x%x,err:0x%x",opcode, result, err);
//     bt_sendprotocoldata(opcode, result, send_buff, 2);
//     if (S_UPDATRE_ACK == opcode) {
//         update_info.recv_index = 0;
//         update_info.update_statu = 0;
//     }
// }

// bool camera_check() {
//     if (camera_get_state() != true) {
//         send_err_code(S_CAMERA_INIT_FAIL, OPCODE_FAIL, 0xffff);
//         return false;
//     }
//     return true;
// }

// void Cmd_CameraSetLight(uint8_t *pData, uint8_t Len) {
//     camera_set_light(pData[2] == 0);
//     bt_sendprotocoldata(S_SET_CAMERA_LIGHT_ACK, 0, NULL, 0);
// }

// void Cmd_CameraReportLight() {
//     bt_sendprotocoldata(S_REPORT_CAMERA_LIGHT_ACK, camera_get_light_satau(), NULL, 0);
// }

// void Cmd_CameraReportStatu() {
//     // 0 正常，1 异常
//     bt_sendprotocoldata(S_REPORT_CAMERA_STATU_ACK, camera_get_state() == false, NULL, 0);
// }



// /**
//   * @brief  Cmd0E process, take picture
//   * @param  pData:The buffer of the data
//   * @param  Len:The length of the data
//   * @retval None
//   */
// void Cmd_ReportImg(uint8_t *pData, uint8_t Len) {
//     camera_fb_t *camera_fb_p = NULL;
//     uint8_t *jpg_data_ptr;
//     uint32_t data_index;
//     uint32_t byte_to_send;
//     uint32_t data_size;
//     uint32_t max_send_len = SPP_PACK_MAX_SIZE - sizeof(SendPackStruct_S);
//     uint16_t light_open_time = 0;
//     uint16_t light_close_time = 0;

//     if (!camera_check()) {
//         return ;
//     }
//     if (Len >= 6) {
//         light_open_time = pData[2] << 8 | pData[3];
//         light_close_time = pData[4] << 8 | pData[5];
//         if (light_open_time > 0) {
//             camera_set_light(true);
//             vTaskDelay(light_open_time / portTICK_PERIOD_MS);
//             camera_set_light(false);
//             vTaskDelay(light_open_time / portTICK_PERIOD_MS);
//         }
//     }
//     ESP_LOGE(TAG, "img get start\n");
//     camera_fb_p = esp_camera_fb_get();
//     if (camera_fb_p == NULL) {
//         send_err_code(S_CAMERA_IMG_ACK, OPCODE_FAIL, 0);
//         ESP_LOGE(TAG, "fb get fail\n");
//         return;
//     }
//     data_size = camera_fb_p->len;
//     if (data_size == 0) {
//         send_err_code(S_CAMERA_IMG_ACK, OPCODE_FAIL, 0);
//         ESP_LOGE(TAG, "img get fail\n");
//         return;
//     }
//     jpg_data_ptr = camera_fb_p->buf;
//     ESP_LOGI(TAG, "size:%dk\n", data_size / 1024);

//     ESP_LOGI(TAG, "width:%d height=%d format=%d len=%d",
//         camera_fb_p->width, camera_fb_p->height, camera_fb_p->format, camera_fb_p->len);
//     uart_write_bytes(UART_USED, (const char*)jpg_data_ptr, data_size);
//     ESP_LOGI(TAG, "uart2 send success!");
//     return;

//         ESP_LOGI(TAG, "report img start");
//         // Step1 Start Pack
//         bt_sendprotocoldata(S_CAMERA_IMG_ACK, OPCODE_START, NULL, 0);

//         ESP_LOGI(TAG, "report img data");
//         //Step2 Data Pack
//         data_index = 0;
//         // Copy data
//         while(data_size > 0) {
//             if(data_size >= max_send_len)
//                 byte_to_send = max_send_len;
//             else
//                 byte_to_send = data_size;
//             bt_sendprotocoldata(S_CAMERA_IMG_ACK, OPCODE_DATA, &jpg_data_ptr[data_index], byte_to_send);
//             data_index += byte_to_send;
//             data_size = data_size - byte_to_send;
//         }
//         ESP_LOGI(TAG, "report img end");
//         //Step3 End Pack
//         bt_sendprotocoldata(S_CAMERA_IMG_ACK, OPCODE_END, NULL, 0);

// }

// void send_updata_index(uint16_t index) {
//     send_buff[0] = index >> 8;
//     send_buff[1] = index;
//     bt_sendprotocoldata(S_UPDATRE_ACK, OPCODE_DATA, send_buff, 2);
// }

// void update_module_init() {
//     memset((char *)&update_info, 0, sizeof(update_info));
//     update_info.update_partition = esp_ota_get_next_update_partition(NULL);
// }

// static void update_start() {
//     int err;

//     //OTA写开始
//     err = esp_ota_begin(update_info.update_partition, OTA_SIZE_UNKNOWN, &update_info.update_handle);
//     if (err != ESP_OK || ((uint32_t)update_info.update_handle == 0)) {
//         ESP_LOGE(TAG, "esp_ota_begin failed, error=%d, handle=%d", err, (uint32_t)update_info.update_handle);
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, err);
//         return ;
//     }
//     ESP_LOGI(TAG, "esp_ota_begin succeeded");
//     bt_sendprotocoldata(S_UPDATRE_ACK, OPCODE_START, NULL, 0);
//     update_info.recv_index =  0;
//     send_updata_index(update_info.recv_index);
//     update_info.update_statu = 1;
// }


// static void update_save(uint8_t *data, uint32_t data_len) {
//     static uint32_t write_total_len = 0;
//     int err;
//     if ((update_info.update_statu != 1) && (update_info.update_statu != 2)) {
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, 0xfffe);
//         return;
//     }

//     //写flash
//     err = esp_ota_write(update_info.update_handle, (const void *)data, data_len);
//     if (err != ESP_OK) {
//         ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x", err);
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, err);
//         return ;
//     }
//     write_total_len += data_len;
//     ESP_LOGI(TAG, "pack index[%d],cur len=%d, total len = %d", update_info.recv_index, data_len, write_total_len);
//     update_info.recv_index++;
//     send_updata_index(update_info.recv_index);
//     update_info.update_statu = 2;
// }

// static void update_end() {
//     int err;
//     if (update_info.update_statu != 2) {
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, 0xfffd);
//         return;
//     }
//     ESP_LOGI(TAG, "esp ota end");
//     if (esp_ota_end(update_info.update_handle) != ESP_OK) {
//         ESP_LOGE(TAG, "esp_ota_end failed!");
//     }
//     bt_sendprotocoldata(S_UPDATRE_ACK, OPCODE_END, NULL, 0);
//     ESP_LOGI(TAG, "esp ota set boot partition");
//     //升级完成更新OTA data区数据，重启时根据OTA data区数据到Flash分区加载执行目标（新）固件
//     err = esp_ota_set_boot_partition(update_info.update_partition);
//     if (err != ESP_OK) {
//         ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err);
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, err);
//         return;
//     }
//     ESP_LOGI(TAG, "Prepare to restart system!");
//     esp_restart();
// }


// void Cmd_Update(uint8_t *pData, uint16_t len) {
//     if (pData[1] == OPCODE_START) {
//         update_start();
//     } else if (pData[1] == OPCODE_DATA) {
//         update_save(pData + 2, len - 2);
//     } else if (pData[1] == OPCODE_END) {
//         update_end();
//     } else {
//         ESP_LOGE(TAG, "Fail update cmd : %d", pData[1]);
//         send_err_code(S_UPDATRE_ACK, OPCODE_FAIL, 0xffff);
//     }
// }

// // 设置相机自动白平衡
// void Cmd_CameraSetAWB(uint8_t enable) {
//     esp_err_t ret;

//     if (!camera_check()) {
//         return ;
//     }

//     ret = camera_set_awb(enable);
//     bt_sendprotocoldata(S_CAMERA_SET_AWB_ACK, ret, NULL, 0);
//     ESP_LOGI(TAG, "camera awb set ret: 0x%d", ret);
// }

// void Cmd_CameraGetAwbStatu() {

//     if (!camera_check()) {
//         return ;
//     }

//     uint8_t ret = camera_get_awb();
//     bt_sendprotocoldata(S_CAMERA_GET_AWB_ACK, ret != 1, NULL, 0);
//     ESP_LOGI(TAG, "camera awb get ret: %d", ret != 1);
// }
// // 设置相机自动曝光时间
// void Cmd_CameraSetAEC(uint16_t aec) {
//     esp_err_t ret;

//     if (!camera_check()) {
//         return ;
//     }

//     ret = camera_set_aec(aec);
//     bt_sendprotocoldata(S_CAMERA_SET_ACE_ACK, ret, NULL, 0);
//     ESP_LOGI(TAG, "camera aec set ret: 0x%d", ret);
// }

// void Cmd_CameraSetImgSize(uint8_t size_index) {
//     esp_err_t ret;

//     if (!camera_check()) {
//         return ;
//     }

//     ret = camera_set_size(size_index);
//     bt_sendprotocoldata(S_CAMERA_SET_IMG_SIZE_ACK, ret, NULL, 0);
//     ESP_LOGI(TAG, "camera size set ret: 0x%d", ret);
// }


// // 数值越小图像质量越高
// void Cmd_CameraSetQuality(uint8_t q) {
//     esp_err_t ret;

//     if (!camera_check()) {
//         return ;
//     }

//     ret = camera_set_quality(q);
//     bt_sendprotocoldata(S_CAMERA_SET_QUALITY_ACK, ret, NULL, 0);
//     ESP_LOGI(TAG, "camera Q set ret: 0x%d", ret);
// }

// void set_bt_name(uint8_t * name,  uint8_t len) {
//     name[len] = 0;
//     strncpy((char *)bt_name, (char *)name, MAX_BT_NAME_SIZE);
//     ESP_LOGI(TAG, "ESP_SPP_INIT_EVT，name:%s",(const char *)bt_name);
//     esp_err_t ret = esp_bt_dev_set_device_name((const char *)bt_name);
//     if (ret == ESP_OK) {
//         ESP_LOGI(TAG, "set_bt_name: Succeed");
//     } else if (ret == ESP_ERR_INVALID_ARG) {
//         ESP_LOGE(TAG, "set_bt_name: if name is NULL pointer or empty, or string length out of limit");
//     } else if (ret == ESP_ERR_INVALID_STATE) {
//         ESP_LOGE(TAG, "set_bt_name:if bluetooth stack is not yet enabled");
//     } else {
//         ESP_LOGE(TAG, "set_bt_name: Fail");
//     }
//     bt_sendprotocoldata(S_SET_BT_NAME_ACK, ret, NULL, 0);
//     ESP_LOGI(TAG, "BT name set ret: 0x%d", ret);
// }

// void report_bt_name() {
//     if (bt_name[0] == 0) {
//         bt_sendprotocoldata(S_REPORT_BT_NAME_ACK, 1, NULL, 0);
//     } else {
//         bt_sendprotocoldata(S_REPORT_BT_NAME_ACK, 0, bt_name, strlen((char *)bt_name) + 1);
//     }
// }

// void report_bt_mac() {
//     uint8_t mac[6];
//     esp_err_t ret = esp_read_mac(mac, ESP_MAC_BT);
//     if (ret != ESP_OK) {
//         ESP_LOGE(TAG, "BT get mac fail! ret: 0x%d", ret);
//         send_err_code(S_REPORT_BT_MAC_ACK, 1, ret);
//     } else {
//         bt_sendprotocoldata(S_REPORT_BT_MAC_ACK, 0, mac, 6);
//         ESP_LOGI(TAG, "BT mac:%x %x %x %x %x %x", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
//     }
// }


// void camera_set_light(bool statu) {
//     if (statu) {
//         gpio_set_level(CAMERA_LIGHT_PIN, 1);
//         camera_light_statu = CAMERA_LIGHT_ON;
//     } else {
//         gpio_set_level(CAMERA_LIGHT_PIN, 0);
//         camera_light_statu = CAMERA_LIGHT_OFF;
//     }
// }

// void camera_set_state(bool state) {
//     camera_state = state;
// }

// bool camera_get_state() {
//     return camera_state;
// }

// void camera_light_init(void) {
//     gpio_pad_select_gpio(CAMERA_LIGHT_PIN);
//     gpio_set_direction(CAMERA_LIGHT_PIN, GPIO_MODE_OUTPUT);
//     camera_set_light(false);
// }

// uint8_t camera_get_light_satau() {
//     return camera_light_statu;
// }

// esp_err_t camera_set_size(uint8_t img_size) {
//     esp_err_t err = 0;
//     if (img_size > FRAMESIZE_QSXGA) {
//         err = ESP_ERR_CAMERA_NOT_SUPPORTED;
//      } else if (s_state->sensor.set_framesize(&s_state->sensor, img_size) != 0) {
// 		err = ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE;
// 	}
//     if (err != 0) {
//         ESP_LOGE(TAG, "Failed to set frame size: err: %d",err);
//     }
//     return err;
// }

// esp_err_t camera_set_quality(uint8_t quality) {
//     (*s_state->sensor.set_quality)(&s_state->sensor, quality);
//     return 0;
// }

// uint8_t camera_set_awb(uint8_t enable) {
//     return 0;
//     // return ov5640_set_awb(&s_state->sensor, enable);
// }

// uint8_t camera_get_awb() {
//     return 0;
//     // return ov5640_get_awb(&s_state->sensor);
// }

// esp_err_t camera_set_aec(uint16_t aec) {
//     esp_err_t ret = ESP_ERR_NOT_FOUND;
//     sensor_t *sensor = &s_state->sensor;
//     return 0;
//     // return ov5640_set_aec(sensor, aec);
// }

// bool is_hs_mode()
// {
//     return s_state->config.xclk_freq_hz > 10000000;
// }